package com.photoeditor.demo.ui.widget;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.photoeditor.R;
import com.photoeditor.demo.util.FontUtil;
import com.photoeditor.demo.util.TouchUtil;


/**
 * listView的快速滑动栏
 */
public class VerticalScrollBar extends RelativeLayout {

    /**
     * 用于touch事件的回调
     */
    private OnScrollBarChangeListener mOnSeekBarChangeListener;

    /**
     * Scroll bar的主体部分
     */
    private LinearLayout mScrollBarLayout;

    /**
     * 用于显示点击后的详情
     */
    private TextView mScrollBarTv;

    /**
     * 未点击时的默认显示
     */
    private ImageView mScrollBarIv;

    /**
     * 整个条的最大值  类似与一个Seek bar 的max
     */
    private int mMax = 100;

    /**
     * 当前的进度
     */
    private int mProgress = 0;

    /**
     * touch down的坐标
     */
    private float mDownY;

    /**
     * 用于缓存上面的外边距
     */
    private float mTopMargin;

    /**
     * 文字和默认显示的图片的间距
     */
    private int mPadding;

    /**
     * 用于记录Text的可见性，动画时是不可见状态的  防止滑动时触摸倒是动画有问题
     */
    private boolean mTextVisible = false;


    private final int ANIMATION_TIME = 240;

    private Handler mHandler;

    private final int MSG_CLOSE_TEXT = 200;
    private final int MSG_SHOW_TEXT = 201;

    public VerticalScrollBar(Context context) {
        super(context);
        initView();
    }

    public VerticalScrollBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        LayoutInflater.from(getContext()).inflate(R.layout.layout_scrollbar, this, true);
        mScrollBarLayout = (LinearLayout) findViewById(R.id.layout);
        mScrollBarTv = (TextView) findViewById(R.id.tv);
        FontUtil.setCustomFont(mScrollBarTv);
        mScrollBarIv = (ImageView) findViewById(R.id.iv);
        mTextVisible = false;
        mScrollBarTv.setVisibility(View.GONE);
        LayoutParams lp = (LayoutParams) mScrollBarLayout.getLayoutParams();
        lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
        lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
        lp.height = getContext().getResources().getDimensionPixelSize(R.dimen.gallery_scroll_bar_height);
        mScrollBarLayout.setLayoutParams(lp);

        mScrollBarLayout.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        mDownY = event.getRawY();
                        LayoutParams lp = (LayoutParams) mScrollBarLayout.getLayoutParams();
                        mTopMargin = lp.topMargin;
                        onStartTrackingTouch();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if ((int) Math.abs(event.getRawY() - mDownY) >= TouchUtil.OFFSET) {
                            refresh(mTopMargin + event.getRawY() - mDownY);
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        onStopTrackingTouch();
//		            refresh(mMargin + event.getRawY() - mDownY);
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        onStopTrackingTouch();
                        break;
                }
                return true;
            }
        });
        mPadding = getContext().getResources().getDimensionPixelSize(R.dimen.gallery_scroll_bar_padding);
        initHandler();
    }

    private void initHandler() {
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == MSG_CLOSE_TEXT) {
                    mScrollBarTv.setWidth(0);
                    mScrollBarTv.setVisibility(View.GONE);
                    mTextVisible = false;
                } else if (msg.what == MSG_SHOW_TEXT) {
                    mTextVisible = true;
                    mScrollBarTv.setText(msg.obj == null ? null : msg.obj.toString());
                }
            }
        };
    }

    private void refresh(float y) {
        int h = getHeight() - mScrollBarLayout.getHeight();
        if (y < 0) y = 0;
        if (y > h) y = h;
        int i = (int) (getMax() * (y * 1.0f / h));
        setProgress(i);
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onProgressChanged(this, i, true);
        }
    }

    public void setMax(int max) {
        mMax = max;
    }

    public int getMax() {
        return mMax;
    }

    public void setProgress(int p) {
        mProgress = p;
        int h = getHeight() - mScrollBarLayout.getHeight();
        int progress = (int) ((p * 1.0f / mMax) * h + 0.5f);
        LayoutParams lp = (LayoutParams) mScrollBarLayout.getLayoutParams();
        lp.topMargin = Math.min(h, progress);
        mScrollBarLayout.setLayoutParams(lp);
    }

    public int getProgress() {
        return mProgress;
    }

    void onStartTrackingTouch() {
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onStartTrackingTouch(this);
        }
    }


    void onStopTrackingTouch() {
        if (mOnSeekBarChangeListener != null) {
            mOnSeekBarChangeListener.onStopTrackingTouch(this);
        }
    }

    public void setOnScrollBarChangeListener(OnScrollBarChangeListener l) {
        mOnSeekBarChangeListener = l;
    }

    public abstract static class OnScrollBarChangeListener {
        private boolean isUserChange = false;

        public abstract void onProgressChanged(VerticalScrollBar scrollbar, int progress,
                                               boolean fromUser);

        public abstract void onStartTrackingTouch(VerticalScrollBar scrollbar);

        public abstract void onStopTrackingTouch(VerticalScrollBar scrollbar);

        public boolean isUserChange() {
            return isUserChange;
        }

        public void setUserChange(boolean isUserChange) {
            this.isUserChange = isUserChange;
        }

    }


    public void setTextViewVisible(boolean visible, final String text) {
        if (visible) {
            float sw = mScrollBarTv.getPaint().measureText(text);
            final int w = (int) (sw + 0.5f) + mPadding;

            mScrollBarTv.setText(null);
            mScrollBarTv.setWidth(0);
            mScrollBarTv.setVisibility(View.VISIBLE);
            mScrollBarTv.post(new Runnable() {

                @Override
                public void run() {
                    ObjectAnimator.ofInt(mScrollBarTv, "width", 0, w).setDuration(ANIMATION_TIME).start();
                    mHandler.removeMessages(MSG_SHOW_TEXT);
                    mHandler.removeMessages(MSG_CLOSE_TEXT);
                    Message msg = Message.obtain(mHandler, MSG_SHOW_TEXT);
                    msg.obj = text;
                    mHandler.sendMessageDelayed(msg, ANIMATION_TIME);
                }
            });
        } else {
            mScrollBarTv.post(new Runnable() {

                @Override
                public void run() {
                    mScrollBarTv.setText(null);
                    int w = mScrollBarTv.getWidth();
                    ObjectAnimator.ofInt(mScrollBarTv, "width", w, 0).setDuration(ANIMATION_TIME).start();
                    mHandler.removeMessages(MSG_SHOW_TEXT);
                    mHandler.removeMessages(MSG_CLOSE_TEXT);
                    mHandler.sendEmptyMessageDelayed(MSG_CLOSE_TEXT, ANIMATION_TIME);
                }
            });
        }
    }

    public boolean getTextViewVisible() {
//		return (mScrollBarTv.getVisibility() == View.VISIBLE);
        return mTextVisible;
    }

    public void setText(String str) {
        float sw = mScrollBarTv.getPaint().measureText(str);
        int w = (int) (sw + 0.5f) + mPadding;
        mScrollBarTv.setText(str);
        mScrollBarTv.setWidth(w);
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
    }
}
